SpringBoot项目集成【用户身份认证】实战 【技术选型篇】基于Session、Token、JWT怎么选? 您所在的位置:网站首页 springboot jwt认证 SpringBoot项目集成【用户身份认证】实战 【技术选型篇】基于Session、Token、JWT怎么选?

SpringBoot项目集成【用户身份认证】实战 【技术选型篇】基于Session、Token、JWT怎么选?

2023-04-03 10:35| 来源: 网络整理| 查看: 265

CSDN成就一亿技术人

本文目录前言专栏介绍一、基于Cookie的Session(会话)认证机制好处:缺点:二、基于Token(令牌)认证机制1. 有状态的Token好处:缺点:2. 无状态的Token好处:缺点:三、JWT1. Header2. Payload3. Signature四、为什么选择JWT?1. 安全2. 无状态3. 可自定义字段最后

前言

在上文,我们实现了基于SpringBoot项目的API接口开发,并实现 API结果统一封装、支持跨域请求等等功能,接下来做的是开发登录接口,实现一套统一鉴权的用户身份认证的机制。

我已经提前和狗哥(博客主页) 一起讨论确定了认证机制,会采用目前流行的基于JWT的Token用户身份认证机制,主流程如下:

前端请求【用户名+密码登录】接口,后端验证通过后生成Token 返回给前端;前端保存Token,以后每次请求API都会携带Token,后端校验Token通过就正常返回数据;直到后端校验Token已失效,这时再从第1步重新开始。 JWT认证流程

为什么这么选型?我们都考虑了哪些点? OK,那我也很乐意和大家一起探讨:怎么做好用户身份认证! 网上很多文章大多直接整合JWT,并没有讲解 为什么选择JWT?与其它选型对比有什么优缺点? 这些都是我们实战的基础,也会让我们代码写的清清楚楚、明明白白。不管写毕业设计,这是面试谈项目亮点,本文也将是你可以参考的点! 用户身份认证很重要,很多小细节,等你收割!相信本文一定会让你有所收获!OK,Let’s go!

PS,完整的用户身份认证代码早已实现,和狗哥也已联调通过,正在赶工博文,预告一下我将分三篇来写,非常详细,料很足,准备好发车喽,Let’s go!

【技术选型篇】基于Session、Token、JWT怎么选?

深入理解Session、Token、JWT

【实战核心篇】基于JWT生成和校验Token

实战基于JWT生成和校验Token

【实战全流程篇】基于JWT+双重检查的登录+登出+拦截器 --防XSS+CSRF漏洞

实战基于JWT+双重检查的登录+登出+拦截器 --防XSS+CSRF漏洞

专栏介绍

因为可能还有很多同学还不清楚上下文,所以简单介绍一下这个专栏要做的事:

天罡老哥和狗哥(博客主页)有意从0到1带大家搭建一个SpringBoot+SpringCloud+Vue的前后端分离项目! 打造一个短小精悍、技术主流、架构规范的前后端分离实战项目!我负责后端,狗哥负责前端! 目的就是让大家通过项目实战,学到一些真东西,将所学理论落地,助力有心强大的你更快的成长!开启你的工作之旅,让开发游刃有余!

详细的后端规划和后端大纲思维导图在开篇已经给出,专栏的总进度如下:

SpringBoot+Vue前后端分离项目实战 - 服务端部分1. 基于SpringBoot+SpringCloud+Vue前后端分离项目实战 --开篇2. 天狗实战SpringBoot+Vue(一)环境安装3. 天狗实战SpringBoot+Vue(二)项目结构搭建(上)4. 天狗实战(二)SpringBoot API开发详解 --SpringMVC注解+封装结果+支持跨域+打包(下)5. Maven依赖加载不进来? 依赖加载失败? 你值得掌握如何排查的方法6. 实战Git常用操作(IDEA界面+命令):初始化(init)、忽略文件(.gitignore)、提交(commit)、查看提交记录(log)、创建+切换分支(branch)Vue + SpringBoot前后端分离项目实战 - 前端部分1. 手把手带你做一套毕业设计-征程开启2. 我应该把毕业设计做到什么程度才能过关?3. 做毕业设计,前端部分你需要掌握的6个核心技能4. 基于Vue+Vue-cli+webpack搭建渐进式高可维护性前端实战项目5. 基于Vue+Less+axios封装+ElementUI搭建项目底层支撑实战6. 使用Vue+vue-router+路由守卫实现路由鉴权功能实战

提前说明:

因为HTTP 是无状态的协议,每个请求都是完全独立的,服务端无法确认当前访问者的身份信息,无法分辨上一次的请求发送者和这一次的发送者是不是同一个人,所以就需要在用户登录后进行登录态的管理。

一、基于Cookie的Session(会话)认证机制

其中有一种是基于Session的方式,是一种记录服务端和浏览器会话状态的机制,大致的流程如下:

登录成功后,服务端根据用户信息生成唯一标识SessionId ,比如根据用户ID+加随机盐salt,然后进行各种加密生成

服务端保存SessionId以及对应的用户信息,比如保存在内存或Redis等,需要维护过期时间。然后将SessionId写入Cookie。

前端请求API时会自动携带Cookie中的SessionId,服务端通过SessionId获取Session进行校验:

如果找到 Session 证明用户已经登录,进行后续处理;如果未找到Session说明用户没有登录或者登录失效,这时再从第1步重新开始。

基于Cookie的Session(会话)认证机制

好处: 因为SessionId保存在Cookie,会自动携带,所以对Web前端来说不需要维护SessionId,非常方便。 缺点: 存在安全问题,因为Cookie自动携带,存在被黑客使用【CSRF跨站请求伪造】攻击的漏洞Cookie无法跨域移动端对Cookie的支持不是很友好服务端需要存储Session,维护过期时间,占用服务器资源,在分布式应用中还需要维护Session同步,另外校验时需要读取Session 二、基于Token(令牌)认证机制

基于Token的认证方式,又分为两种:

1. 有状态的Token

有状态的Token方式,服务端需要保存Token数据

比如, 将基于Cookie的Session方式变一变,不基于Cookie了,而是由前端自行维护Token,大致的流程如下:

登录成功后,服务端根据用户信息生成唯一标识TokenId ,比如根据用户ID+加随机盐salt,然后进行各种加密生成

服务端保存TokenId以及对应的用户信息,比如保存在内存或Redis等,需要维护过期时间。然后将TokenId返回给前端。

因为不基于Cookie,所以前端需要自行保存TokenId,比如保存在localStorage等,请求API时控制携带TokenId,服务端通过TokenId去内存或Redis搜索匹配的Token:

如果找到Token,证明用户已经登录,进行后续处理;如果未找到Token,说明用户没有登录或者登录失效,这时再从第1步重新开始。

基于有状态Token(令牌)认证机制

当Token不需要保存除用户ID之外的信息时,Token就等于TokenId,只是保存的信息变少,但仍然需要服务端保存,例如保存在内存中的话就是数据结构用Map还是Set的区别,或者Map的value是不是空的区别。

好处: 因为Token完全由前端维护,不基于Cookie,所以可以避免CSRF攻击、支持跨域、对移动端友好。 缺点: 和Session方式有同样的缺点:服务端需要存储Token,维护过期时间,占用服务器资源,在分布式应用中还需要维护Token同步,另外校验时需要读取Token

当然还有其它场景:

比如,你申请调用第三方平台的接口,它会为你生成一个一直有效的Token,那么这个Token就是保存在第三方的服务端,也是有状态的。再比如,你可能听说过refresh_token,用于刷新access_token,access_token可以不用在服务端保存,但refresh_token还需要保存在服务端,这些都可以称为有状态的。 2. 无状态的Token

无状态的Token方式,服务端不用保存Token数据,是不是听上去很历害?大致的流程如下:

登录成功后,服务端生成Token 返回给前端;前端保存Token,比如保存在localStorage等,请求API时控制携带Token,服务端接收后校验Token: 校验Token通过,进行后续处理;校验Token不通过,说明用户没有登录或者登录失效,这时再从第1步重新开始。

基于无状态Token(令牌)认证机制

好处: 因为Token完全由前端维护,不基于Cookie,所以可以避免CSRF攻击、支持跨域、对移动端友好。服务端不需要维护Token,节省了服务器资源,在分布式应用中更多省去了很多麻烦 缺点: 也正是因为服务端没有保存Token,引申出来Token无法主动过期的问题。颁发后在过期时间内就会一直有效,所以在主动登出时需要处理如何让Token主动失效。 三、JWT

JWT (JSON Web Token) 是一种开放标准(RFC 7519)定义的JSON对象,本质是一个字符串,正是无状态Token中的一种。那它是如何做到不用服务端保存,仅通过自身就能完成校验?

这和人民币防伪有点类似,是因为它本身既包含用户信息等数据,也包含过期时间和数字签名,虽然数据经过传输,但接收方仍可以直接校验它是否过期、是否被篡改!

还没理解?那我们看一下它的组成:

JWT组成

如上图右侧是解码后的数据,左侧是JWT字符串,由图中3种颜色代表的3个部分组成(以逗号连接):

1Header.2Payload.3Signature

1. Header

元数据,定义了生成签名的算法以及 Token 的类型。

{"typ": "JWT","alg": "RS256" }

typ:表示Token类型,JWT统一为JWT

alg:表示签名算法,像RS256、HS256

2. Payload

载荷,是传递数据的载体,包含7个内置字段:

String ISSUER = "iss"; // 发行人 String SUBJECT = "sub"; // 主题 String EXPIRES_AT = "exp"; // 失效时间 String NOT_BEFORE = "nbf"; // 在此之前不可用 String ISSUED_AT = "iat"; // 发布时间 String JWT_ID = "jti"; // JWT id值 String AUDIENCE = "aud"; // 用户

重点是 exp 失效时间 ,其它可选使用,例如:我可以将 iss 指定保存userId

用户信息就保存在这里,上面7个不够的话,还可以自定义字段,例如:我自定义了userName:

{"sub": "TgAuthSSO","nbf": 1679984611,"iss": "1","exp": 1679984911,"userName": "张三","iat": 1679984611 }

注意:payload中数据默认未加密,所以不适合放隐私信息字段,比如用户的密码等,防止信息泄露。

3. Signature

签名,这是JWT防止内容被篡改的关键!

通过使用 Header 里面指定的签名算法,对Payload和Header加密而生成。

四、为什么选择JWT? 1. 安全

数据被签名加密后,可以有效防止内容被篡改。

例如:RSA算法,目前仍是非常可靠的加密算法,极难破解!

2. 无状态

【无状态】是相对【有状态】而言,【有状态】是指服务器端需要保存数据。

JWT由于其自带校验的所有数据,本身就可以验证Token是否被篡改、是否合法、是否过期,所以不需要在服务器存储Token,对于分布式场景省去了很多麻烦,更主要的是节省了服务器资源!

3. 可自定义字段

能够在Payload中自定义存储字段,保证了扩展性,可以把常用数据写进去,避免数据的二次读取。

最后

如果觉得写的不错,订阅起来吧,后面还有更多干货输出… ,我会针对订阅的同学做针对性的指导,让你能轻松的将项目完整实战跟下来,OK,就说这么多了,我们下文见! 另外,别忘了关注天哥:天罡gg ,发布新文不容易错过: https://blog.csdn.net/scm_2008

老规矩,请投票给我反馈,谢谢大家的支持!



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有